﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FinPlusCommon;
using log = Logger.Logger;

namespace FinPlusWPFControls
{
    public partial class FinPlusChartCandleStick : FinPlusControl
    {
        private IFinPlusComp _conn;
        private IFunctions _funcs;
        private string[] _fields, _titles;

        //construct
        public FinPlusChartCandleStick(IFinPlusComp connection, string[] fields, string[] titles)
        {
            InitializeComponent();
            _fields = fields;
            _titles = titles;
            IsValid = true;
            AddConnection((FinPlusConnectService)connection);
        }

        //common control interface
        public override void Dispose()
        {
            try
            {
                if (_conn != null)
                    _conn.Dispose();
            }
            catch (Exception e)
            {
                log.Log(Logger.Level.Warning, Id, Config, e.Message, e);
            }
        }

        //private
        private async void AddConnection(FinPlusConnectService conn)
        {
            try
            {
                 _conn = conn;
                 _funcs = conn.GetFunctions();
                 var dataPoints = await Task.Run(() => { return new CandleStickDataPoints(_funcs, _fields); });
                 series.DataContext = dataPoints.Values.ToList();
                 chart.Title = ChartFormaters.GetTitle(_funcs.Values.First(), _titles, TimeSpan.MinValue, dataPoints.Start, dataPoints.End, "dd-MM-yy H:mm");
            }
            catch (ServiceConnException e)
            {
                IsValid = log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        //private classes
        private class CandleStickDataPoints : Dictionary<string, CandleStickDataPoint>
        {
            public DateTime Start, End;

            private IFunctions _funcs;
            private string[] _fields;

            public CandleStickDataPoints(IFunctions funcs, string[] fields)
            {
                _fields = fields;
                _funcs = funcs;
                Initialise();
            }

            //private
            private void Initialise()
            {
                foreach (var type in _fields)
                {
                    var res = _funcs.Where(string.Format("Name='Info' And Value='{0}'", type));
                    if (res.Count() < 1) continue;

                    foreach (var item in res.First().Value)
                    {
                        if (item.Index < 7) continue;

                        CandleStickDataPoint dataPoint;
                        if (!this.ContainsKey(item.Name))
                            this[item.Name] = dataPoint = new CandleStickDataPoint();
                        else
                            dataPoint = this[item.Name];

                        if (Start.Equals(DateTime.MinValue)) Start = dataPoint.DateTime;

                        dataPoint.Add(item, type);
                    }

                    End = this.Last().Value.DateTime;
                }
            }
        }

        private class CandleStickDataPoint : ChartDataPoint
        {
            public double WickLength { get { return High - Low; } }
            public double BodyHigh { get { return Open > Close ? Open : Close; } }
            public double BodyLength { get { return Math.Abs(Open - Close); } }
            public double BodyDiff { get { return High - BodyHigh; } }
            public bool Up { get { return Open < Close; } }
        }
    }
}
